Table des matières

Installer son serveur DNS faisant autorité avec NSD

Les glue records

Installer le serveur primaire

Gérer ses zones

Autoriser les serveurs secondaires

Devenir serveur secondaire

Éditer le fichier de zone

Le serial

Tester

Conclusion

Signer sa zone DNS avec OpenDNSSEC

Mini-introduction à DNSSEC

Pour commencer

Installation des paquets

Configuration de SoftHSM

Configuration d'OpenDNSSEC

Configuration générale

Configuration Kasp

Ajout de la zone à signer

Publier l'enregistrement DS

Monitoring

Conclusion

Installer son propre DNS avec Unbound

Installer son serveur DNS faisant autorité avec NSD

 
 

Publié le 16/01/2020

Quand on a réservé un nom de domaine auprès d'un bureau d'enregistrement ce dernier propose souvent d'utiliser ses serveurs DNS pour faire autorité sur la zone. Mais servir sa zone avec ses propres serveurs DNS est bien plus amusant et c'est ce que nous allons faire aujourd'hui à l'aide du logiciel NSD.

Quand il s'agit d'installer un serveur DNS, que ce soit un résolveur ou un serveur faisant autorité, les yeux se tournent systématiquement vers Bind. C'est souvent un choix fait "par défaut" ou parce que c'est celui qui est enseigné en cours et qu'il fait à la fois résolveur et serveur faisant autorité. Cependant il existe bien d'autres logiciels pour servir des zones comme Knot, PowerDNS ou NSD et c'est ce dernier que j'utilise.

Dans cet article je vais prendre pour exemple la zone lithio.fr.

Les glue records

Pour commencer il faut dire à la zone parent qui sont les serveurs DNS faisant autorité sur notre zone en créant des Glue Records.

Parler de Glue Record dans un cours c'est en général un bon moyen de voir si les étudiant⋅e⋅s suivent. On énonce :

"Et donc la zone parent annonce que le DNS faisant autorité pour example.com est ns1.example.com"

et on voit ce qui se passe. Il y en a en général un⋅e pour dire :

"Mais si le parent dit que le DNS qui fait autorité pour example.com c'est ns1.example.com alors il faut résoudre le nom de ns1.example.com, sauf que c'est justement ns1.example.com qui a cette info !"

Et c'est vrai, c'est un problème de l'œuf et de la poule et on résout ça dans le DNS en mettant quand même dans la zone parent les enregistrement A et AAAA des serveurs DNS faisant autorité sur notre zone, en plus des enregistrements NS.

Cela se passe souvent dans l'interface du bureau d'enregistrement où on renseigne les noms et IP dans des champs Glue Record.

Installer le serveur primaire

Nous installons NSD :

# apt install nsd

Nous modifions la configuration principale dans /etc/nsd/nsd.conf :

server:

  ip-address: 198.51.200.1

  ip-address: 2001:db8::1

 

  port: 53

 

  server-count: 1

 

  hide-version: yes

 

  identity: "ns1.lithio.fr"

 

  zonesdir: "/var/lib/nsd/zones"

 

  logfile: "/var/log/nsd.log"

  pidfile: "/run/nsd/nsd.pid"

 

  include: "/etc/nsd/nsd.conf.d/*.conf"

Cette configuration indique les adresses IP et ports sur lesquelles le serveur doit écouter, le nombre de threads ou encore le dossier qui contient les fichiers de zones.

Gérer ses zones

Pour chaque zone que nous gérons nous allons créer un fichier de configuration dans /etc/nsd/nsd.conf.d/.

Nous éditons le fichier /etc/nsd/nsd.conf.d/lithio.fr.conf :

zone:

    name: lithio.fr

    zonefile: lithio.fr

On indique que l'on crée une zone dont le nom est lithio.fr et dont le fichier de zone se nomme aussi ainsi relativement au chemin indiqué par zonesdir dans la configuration principale de NSD.

Autoriser les serveurs secondaires

Avoir un seul serveur DNS faisant autorité n'est vraiment pas une bonne idée car si ce dernier vient à tomber en panne ou à être inaccessible par exemple alors il devient impossible d'obtenir des réponses pour notre zone.

On fait donc attention à avoir des serveurs secondaires (Les siens, ceux d'amis, etc) qui vont se mettre à jour régulièrement en récupérant le fichier de zone auprès du serveur primaire. Pour cela il suffit de dire dans la partie zone quelles sont les IP et ports des serveurs secondaires que l'on souhaite notifier lors d'un changement dans la zone et qu'on autorise à faire du XFR.

On ajoute donc les champs notify et provide-xfr :

zone:

    name: lithio.fr

    zonefile: lithio.fr

    notify: 198.51.100.1@53 NOKEY

    provide-xfr: 198.51.100.1 NOKEY

On remarque que j'ai ajouté un NOKEY à la fin de ces lignes car il est aussi possible (et c'est recommandé) d'ajouter de l'authentification entre les primaires et les secondaires en utilisant une clé commune.

On ajoute une section key à notre configuration et on y crée une clé en précisant l'algorithme et le secret :

zone:

    name: lithio.fr

    zonefile: lithio.fr

    notify: 198.51.100.2@53 friend_key

    provide-xfr: 198.51.200.1 friend_key

 

key:

    name: "friend_key"

    algorithm: hmac-sha256

    secret: "4zzNa5Hsd3qr8MBrh65xYnfOPWW+PRhQC/T5T1NDqLc="

Le secret est encodé en base64, par exemple avec cette commande :

dd if=/dev/random of=/dev/stdout count=1 bs=32 | base64

Devenir serveur secondaire

Quand on veut du coup configurer ses serveurs secondaires ou être serveur secondaire d'une zone, il faut déclarer sa zone de la même manière mais en précisant qui sont les serveurs primaires.

zone:

    name: lithio.fr

    zonefile: lithio.fr

    allow-notify: 198.51.100.1 friend_key

    request-xfr: AXFR 198.51.100.1@53 friend_key

 

key:

    name: "friend_key"

    algorithm: hmac-sha256

    secret: "4zzNa5Hsd3qr8MBrh65xYnfOPWW+PRhQC/T5T1NDqLc="

Cette fois-ci avec un allow-notify pour renseigner les IP autorisées à nous notifier d'un changement dans une zone.

On oublie pas de recharger la configuration de NSD une fois modifié :

# systemctl reload nsd

Éditer le fichier de zone

Comme vu plus haut notre fichier de zone est /var/lib/nsd/zones/lithio.fr, en voici un exemple :

$ORIGIN lithio.fr.

$TTL 3600

@               IN      SOA ns1.lithio.fr. contact.lithio.fr. (

                        2020010807      ; serial

                        86400           ; refresh

                        3600            ; retry

                        3600000         ; expire

                        3600            ; ttl

                )

 

; NS Servers

@               IN      NS      ns1.lithio.fr.

@               IN      NS      ns2.lithio.fr.

 

; A Records

@               IN      A       51.254.121.3

ns1             IN      A       51.254.121.3

ns2             IN      A       80.67.176.37

toutetrien      IN      A       51.254.121.3

 

; AAAA Records

@               IN      AAAA    2001:41d0:401:3000::b8a

ns1             IN      AAAA    2001:41d0:401:3000::b8a

ns2             IN      AAAA    2001:910:1025:1::1

toutetrien      IN      AAAA    2001:41d0:401:3000::b8a

Chaque ligne (ou ensemble de ligne quand il y a des parenthèses) est un enregistrement qui s'écrit de la manière suivante :

Nom     TTL     Classe  Type    Taille  Donnée

Tout cela est expliqué dans la section 3 du RFC 1035, on retrouve généralement :

Pour expliquer rapidement ce que l'on voit au début du fichier (Cf section 5 du RFC 1035) :

Donc pour mettre à jour notre zone DNS il nous suffit de modifier le fichier puis de dire à NSD de recharger la zone, avec la commande :

$ nsd-control reload lithio.fr

Le serial

Vous avez surement remarqué que dans l'enregistrement SOA de notre zone la troisième valeur se nomme serial. Il s'agit du numéro de version de notre fichier de zone, il faut donc l'incrémenter à chaque modification du fichier.

Il ne faut surtout pas oublier de le faire sans quoi les serveurs secondaires ne voudront pas récupérer la nouvelle version de la zone.

Quant à quoi mettre comme serial, la section 2.2 du RFC 1912 recommande d'utiliser la date du jour suivie d'un nombre (YYYYMMDDnn).

Tester

On peut facilement tester que tel ou tel serveur réponde bien avec un outil comme Drill :

$ drill @ns1.lithio.fr A lithio.fr

;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 38363

;; flags: qr aa rd ; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 4

;; QUESTION SECTION:

;; lithio.fr.   IN  A

 

;; ANSWER SECTION:

lithio.fr.  3600    IN  A   51.254.121.3

 

;; AUTHORITY SECTION:

lithio.fr.  3600    IN  NS  ns1.lithio.fr.

lithio.fr.  3600    IN  NS  ns2.lithio.fr.

 

;; ADDITIONAL SECTION:

ns1.lithio.fr.  3600    IN  A   51.254.121.3

ns2.lithio.fr.  3600    IN  A   80.67.176.37

ns1.lithio.fr.  3600    IN  AAAA    2001:41d0:401:3000::b8a

ns2.lithio.fr.  3600    IN  AAAA    2001:910:1025:1::1

 

;; Query time: 21 msec

;; SERVER: 51.254.121.3

;; WHEN: Fri Jan 17 14:47:53 2020

;; MSG SIZE  rcvd: 167

Conclusion

Au final malgré la quantité d'informations, gérer ses serveurs DNS faisant autorité est plutôt simple. La partie plus complexe arrive quand on souhaite ajouter de la sécurité avec DNSSEC (ce qu'il faut faire) mais ça fera l'objet d'un prochain article.

Signer sa zone DNS avec OpenDNSSEC

 
 

Publié le 19/05/2020

Aujourd'hui nous allons voir comment signer notre zone DNS avec DNSSEC, car gérer son DNS faisant autorité c'est rigolo mais y ajouter DNSSEC ça l'est aussi. DNSSEC est le protocole qui permet de sécuriser les données du DNS en signant cryptographiquement les enregistrements de zone DNS.

Je ne vais pas lister ici les bonnes raisons de signer sa zone avec DNSSEC car il existe de nombreux articles sur le sujet et en 2020 un ou une bon⋅ne adminsys sait qu'il faut signer ses zones. Il existe également de bons articles techniques (attention toutefois à bien vérifier la version d'OpenDNSSEC utilisée car les commandes, entre autres, changent entre la version 1 et 2) utiles à lire.

Si vous utilisez FreeBSD, cet article est également disponible sur https://adminblog.foucry.net/posts/info/dnssec/.

Mini-introduction à DNSSEC

Le but de DNSSEC est que l'utilisateur final (ou plutôt son résolveur) puisse établir une chaîne de confiance entre la racine (en qui le résolveur a déjà confiance car il en connaît les clés au démarrage) et le DNS faisant autorité sur la zone lui donnant la réponse à sa requête.

En théorie le fonctionnement est le suivant :

Par exemple pour lithio.fr :

Au final on a donc la racine qui signe ses réponses avec la clé A, fr qui signe ses réponses avec la clé B et lithio.fr qui signe ses réponses avec la clé C. On a de base confiance en A, A a confiance en B et B a confiance en C : ainsi on fait confiance aux réponses de lithio.fr via toute la chaîne.

Cet exemple sert juste d'explication car dans les faits chaque zone n'a pas une clé mais plusieurs : les KSK (Key Signing Keys) et les ZSK (Zone Signing Key). Les KSK sont comme les clés A, B et C de notre exemple sauf qu'au lieu de signer directement les enregistrements DNS de la zone, elles vont signer des ZSK qui, elles, vont signer les enregistrements de la zone. La chaîne de confiance suit toujours le même principe sauf qu'il y a plus d'élements. À noter que les hash de la clé fille dans la zone parente sont appelés DS (Delegation Signer).

Pour prendre un exemple concret :

dnssec-lithiofrdnssec-lithiofr
 

Schéma DNSSEC de lithio.fr

Dans ce schéma qui représente la chaîne DNSSEC jusqu'à lithio.fr :

On peut également voir cette arborescence en utilisant drill :

$ drill -S lithio.fr SOA

;; Number of trusted keys: 2

;; Chasing: lithio.fr. SOA

 

 

DNSSEC Trust tree:

lithio.fr. (SOA)

|---lithio.fr. (DNSKEY keytag: 6378 alg: 8 flags: 256)

    |---lithio.fr. (DNSKEY keytag: 65035 alg: 8 flags: 257)

    |---lithio.fr. (DS keytag: 65035 digest type: 2)

        |---fr. (DNSKEY keytag: 28756 alg: 8 flags: 256)

            |---fr. (DNSKEY keytag: 35095 alg: 8 flags: 257)

            |---fr. (DS keytag: 35095 digest type: 2)

                |---. (DNSKEY keytag: 22545 alg: 8 flags: 256)

                    |---. (DNSKEY keytag: 20326 alg: 8 flags: 257)

;; Chase successful

Ainsi, en ayant confiance uniquement en une clé de la racine, on peut vérifier les réponses de toute la chaîne.

Pour commencer

Dans cet article nous allons nous intéresser uniquement à la dernière partie (avec lithio.fr). Notre but va être de générer une KSK, de transmettre le DS à la zone parente pour que celle-ci puisse dire que l'on signe avec cette KSK, et d'utiliser la KSK pour signer des ZSK qui vont elles-mêmes signer les enregistrements DNS de notre zone.

Dans cet article je pars du principe que vous gérez déjà votre propre DNS faisant autorité (avec Bind ou NSD par exemple).

Dans le cadre des tests de cet article j'utilise des machines sous Debian 10 et nous allons signer la zone dnssec.lithio.fr (créée et active uniquement pour ces tests), cette zone ainsi que sa zone parente lithio.fr sont gérées par le logiciel NSD.

Nous allons donc devoir :

Installation des paquets

On installe OpenDNSSEC et SoftHSM2 :

# apt install opendnssec softhsm2

OpenDNSSEC est le logiciel qui va s'occuper de la signature de la zone, la génération et la rotation des clés en suivant une politique que nous lui indiquerons. SoftHSM2 est un HSM logiciel (car nous n'avons pas de HSM matériel), SoftHSM est utilisé pour stocker des clés cryptographiques.

Configuration de SoftHSM

On crée un slot HSM sur le slot 0 avec l'étiquette (TokenLabel) OpenDNSSEC, il nous demande un code pin administrateur et utilisateur (je mets 1234 pour l'exemple mais bien sûr il faut en mettre des plus sûrs).

# softhsm2-util --init-token --slot 0 --label "OpenDNSSEC"

=== SO PIN (4-255 characters) ===

Please enter SO PIN: ****

Please reenter SO PIN: ****

=== User PIN (4-255 characters) ===

Please enter user PIN: ****

Please reenter user PIN: ****

The token has been initialized and is reassigned to slot 364027858

On peut vérifier les informations avec la commande suivante.

# softhsm2-util --show-slots

Available slots:

Slot 364027858

    Slot info:

        Description:      SoftHSM slot ID 0x15b29fd2                                      

        Manufacturer ID:  SoftHSM project                

        Hardware version: 2.4

        Firmware version: 2.4

        Token present:    yes

    Token info:

        Manufacturer ID:  SoftHSM project                

        Model:            SoftHSM v2      

        Hardware version: 2.4

        Firmware version: 2.4

        Serial number:    6b9fa0e695b29fd2

        Initialized:      yes

        User PIN init.:   yes

        Label:            OpenDNSSEC

Configuration d'OpenDNSSEC

OpenDNSSEC contient 2 outils principaux qui nous intéressent : "l'enforcer" et "le signer".

L'enforcer s'occupe de faire appliquer les politiques et le signer, et bien, signe.

Configuration générale

En éditant /etc/opendnssec/conf.xml.

On modifie le bloc du HSM pour indiquer à OpenDNSSEC où sont stockées nos clés ainsi que le pin :

<Repository name="SoftHSM">

    <Module>/usr/lib/softhsm/libsofthsm2.so</Module>

    <TokenLabel>OpenDNSSEC</TokenLabel>

    <PIN>1234</PIN>

    <SkipPublicKey/>

</Repository>

On ne touche pas à la configuration Common qui est bien comme elle est.

Les clés (surtout les ZSK) sont régulièrement changées, le logiciel en génère donc à l'avance pour assurer le remplacement de manière fluide. On va modifier la configuration de l'enforcer, pour générer nos clés 1 jour en avance.

<Enforcer>

    <Datastore><SQLite>/var/lib/opendnssec/kasp.db</SQLite></Datastore>

    <AutomaticKeyGenerationPeriod>P1D</AutomaticKeyGenerationPeriod>

 

    <WorkingDirectory>/var/lib/opendnssec/enforcer</WorkingDirectory>

 

    <WorkerThreads>2</WorkerThreads>

</Enforcer>

On va modifier la configuration du signer pour signaler - une fois la zone signée - à NSD de recharger la zone (à adapter en fonction du logiciel que vous utilisez).

<Signer>

 

    <WorkingDirectory>/var/lib/opendnssec/signer</WorkingDirectory>

    <WorkerThreads>2</WorkerThreads>

 

    <!-- the <NotifyCommmand> will expand the following variables:

 

         %zone      the name of the zone that was signed

         %zonefile  the filename of the signed zone

    -->

 

    <NotifyCommand>/usr/sbin/nsd-control reload %zone</NotifyCommand>

 

</Signer>

On constate également qu'il n'y a pour le moment aucune clé générée :

# ods-hsmutil list

 

Listing keys in all repositories.

0 keys found.

 

Repository            ID                                Type      

----------            --

Configuration Kasp

KASP pour "Key And Signature Policy" est la configuration qui contient les politiques de génération et renouvellement des clés. Le mieux pour bien en comprendre le fonctionnement est d'en lire la documentation.

On va modifier /etc/opendnssec/kasp.xml.

Nous devons ici éditer la configuration que nous allons utiliser, il y en a de base 2 : default (qui a d'ailleurs comme description A default policy that will amaze you and your friends, comme quoi on rigole bien dans le monde du DNS) et lab. Dans le cadre de ce test je vais utiliser lab, mais en production il est préférable d'en utiliser d'autres, si, par exemple, vous souhaitez signer un domaine dont la zone parente est fr, l'AFNIC à mis à disposition un document sur le sujet.

On voit également qu'on peut indiquer les algorithmes utilisés pour générer les clés, par défaut c'est le 8 (RSA-SHA256) qui est utilisé. Pour savoir quoi mettre la section 3.1 du RFC 8624 est bien utile en nous donnant un tableau qui contient les algorithmes que l'on doit, ne doit pas ou devrait employer. Je vais utiliser ici le 13 (ECDSAP256SHA256) et indique que le renouvellement de la KSK est manuel (car il faudra l'envoyer à la zone parente à la main) :

<KSK>

    <Algorithm length="512">13</Algorithm>

    <Lifetime>P1Y</Lifetime>

    <Repository>SoftHSM</Repository>

    <ManualRollover/>

</KSK>

<ZSK>

    <Algorithm length="512">13</Algorithm>

    <Lifetime>PT4H</Lifetime>

    <Repository>SoftHSM</Repository>

</ZSK>

À noter que dans ce fichier les périodes de temps sont indiquées au format ISO 8601 (comme expliqué dans la documentation). À noter également que les valeurs sont fixes : 1Y (un an) vaudra toujours 365 jours, même les années bissextiles; 1M (un mois) vaudra toujours 31 jours, même en février.

On vérifie que notre configuration soit correcte :

# ods-kaspcheck

On initialise la base de données de l'enforcer avec la commande (on ne le fait que la première fois, plus jamais ensuite) :

# ods-enforcer-db-setup

On supprime le fichier /etc/opendnssec/prevent-startup qui empêche le lancement d'OpenDNSSEC tant que celui-ci n'est pas configuré et on lance l'enforcer et le signer DNSSEC :

# systemctl start opendnssec-enforcer

# systemctl start opendnssec-signer

On importe nos politiques :

# ods-enforcer policy import

Normalement tout est prêt pour commencer à gérer nos zones.

Ajout de la zone à signer

OpenDNSSEC prévoit de mettre les fichiers de zones dans /var/lib/opendnssec/unsigned/ et de voir le résultat signé dans /var/lib/opendnssec/signed/, dans notre cas nous avons /var/lib/opendnssec/unsigned/dnssec.lithio.fr.

Avant il fallait renseigner les zones dans le fichier /etc/opendnssec/zonelist.xml mais, comme il nous l'indique, cela a changé depuis la version 2.0 et il faut considérer la base de données de l'enforcer comme référence. Nous allons donc ajouter la zone dans la base puis exporter cette dernière dans le fichier zonelist.xml.

On ajoute notre zone à l'enforcer :

# ods-enforcer zone add --zone dnssec.lithio.fr --policy lab --input /var/lib/opendnssec/unsigned/dnssec.lithio.fr --output /var/lib/opendnssec/signed/dnssec.lithio.fr

Après chaque ajout de zone on joue la commande d'export afin de tenir le fichier zonelist.xml à jour :

# ods-enforcer zonelist export

Notre zone est normalement immédiatement signée et on peut vérifier ça dans les logs et dans le fichier de sortie.

On peut voir les clés dans notre HSM :

# ods-hsmutil list

 

Listing keys in all repositories.

9 keys found.

 

Repository            ID                                Type      

----------            --                                ----      

SoftHSM               1aa9234b8deeb67654e0a54073f1810f  ECDSA/256

SoftHSM               4fc296406405101f2ff07d5b57dbc3f9  ECDSA/256

SoftHSM               15be78d2934f0fffdbb56cf7be69e50a  ECDSA/256

SoftHSM               8b03481c104686d88c7e59d09043e776  ECDSA/256

SoftHSM               b53d288301fcaf678bffb152cf13ff80  ECDSA/256

SoftHSM               a755e62000e11e194c7d93a3b2c09395  ECDSA/256

SoftHSM               3f81735b5e1913ccfd0c15adafae47d9  ECDSA/256

SoftHSM               45a1dddc8e01d69c62de4a956efbd419  ECDSA/256

SoftHSM               2747f82955fea88a4495b94fc4f001be  ECDSA/256

À présent il faut indiquer à notre logiciel de DNS faisant autorité sur la zone d'utiliser ce nouveau fichier contenant les signatures DNSSEC.

On vérifie ensuite que les enregistrements RRSIG soient bien présents avec dig (en demandant directement à un serveur faisant autorité sur la zone pour éviter une réponse provenant du cache du résolveur) :

$ dig @dnssec.lithio.fr +dnssec dnssec.lithio.fr

 

; <<>> DiG 9.11.5-P4-5.1-Debian <<>> +dnssec dnssec.lithio.fr

;; global options: +cmd

;; Got answer:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15101

;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 1

;; WARNING: recursion requested but not available

 

;; OPT PSEUDOSECTION:

; EDNS: version: 0, flags: do; udp: 4096

;; QUESTION SECTION:

;dnssec.lithio.fr.      IN  A

 

;; ANSWER SECTION:

dnssec.lithio.fr.   56  IN  A   54.37.69.174

dnssec.lithio.fr.   56  IN  RRSIG   A 13 3 60 20200102143140 20200102123044 17006 dnssec.lithio.fr. CNz7ipxye839NwTm2C3xXpCisJaSWBpfgCe1ZMCakmZc0NZ+rODXPWi/ Z1E25CkuKEa86Rg/NGl3tcU56K2o0A==

On note qu'il n'y a pas le flag ad, indiquant que le résolveur n'a pas validé avec DNSSEC. C'est normal car nous demandons directement à un serveur faisant autorité, si nous demandions à un résolveur validant DNSSEC nous ne l'aurions pas non plus car la zone parente ne possède pas encore l'enregistrement DS prouvant que notre zone doit être signée.

Publier l'enregistrement DS

On vérifie l'état de notre zone :

# ods-enforcer key list --verbose --all --zone dnssec.lithio.fr

Keys:

Zone:                           Keytype: State:    Date of next transition: Size: Algorithm: CKA_ID:                          Repository: KeyTag:

dnssec.lithio.fr                KSK      publish   2020-01-02 14:40:44      512   13         2747f82955fea88a4495b94fc4f001be SoftHSM     54859

dnssec.lithio.fr                ZSK      ready     2020-01-02 14:40:44      512   13         1aa9234b8deeb67654e0a54073f1810f SoftHSM     17006

La KSK est en état publish, on attend qu'elle passe en état ready (on voit qu'elle attend qu'on lui indique que le DS est bien visible) :

# ods-enforcer key list --verbose --all --zone dnssec.lithio.fr

Keys:

Zone:                           Keytype: State:    Date of next transition: Size: Algorithm: CKA_ID:                          Repository: KeyTag:

dnssec.lithio.fr                KSK      ready     waiting for ds-seen      512   13         2747f82955fea88a4495b94fc4f001be SoftHSM     54859

dnssec.lithio.fr                ZSK      active    2020-01-02 18:30:44      512   13         1aa9234b8deeb67654e0a54073f1810f SoftHSM     17006

On exporte alors son DS :

# ods-enforcer key export --zone dnssec.lithio.fr --ds

;ready KSK DS record (SHA256):

dnssec.lithio.fr.   3600    IN  DS  54859 13 2 b0f3c176f7f8d5a8712f87582b462d4e7f7450da7a8f24e2f2bb71c0fc212356

On le transmet à la zone parente. Dans mon cas je l'ajoute à la zone lithio.fr mais sinon, il faut en général le transmettre via votre bureau d'enregistrement, qui doit avoir un formulaire pour cela.

Une fois le temps de juvénisation passé, on indique à l'enforcer que l'enregistrement DS à été "vu" et que l'on peut signer avec en précisant la KSK en question (son keytag) :

# ods-enforcer key ds-seen --zone dnssec.lithio.fr --keytag 54859

1 KSK matches found.

1 KSKs changed.

On constate que notre KSK est à présent active :

# ods-enforcer key list -v --all --zone dnssec.lithio.fr

Keys:

Zone:                           Keytype: State:    Date of next transition: Size: Algorithm: CKA_ID:                          Repository: KeyTag:

dnssec.lithio.fr                KSK      active    2020-01-02 18:30:44      512   13         2747f82955fea88a4495b94fc4f001be SoftHSM     54859

dnssec.lithio.fr                ZSK      active    2020-01-02 18:30:44      512   13         1aa9234b8deeb67654e0a54073f1810f SoftHSM     17006

On vérifie avec dig, normalement notre zone est à présent signée et le flag ad présent (attention à ce que le résolveur utilisé ne transmette pas une réponse du cache) :

$ dig +dnssec dnssec.lithio.fr

; <<>> DiG 9.11.5-P4-5.1-Debian <<>> +dnssec dnssec.lithio.fr

;; global options: +cmd

;; Got answer:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3212

;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

 

;; OPT PSEUDOSECTION:

; EDNS: version: 0, flags: do; udp: 4096

;; QUESTION SECTION:

;dnssec.lithio.fr.      IN  A

 

;; ANSWER SECTION:

dnssec.lithio.fr.   60  IN  A   54.37.69.174

dnssec.lithio.fr.   60  IN  RRSIG   A 13 3 60 20200102143140 20200102123044 17006 dnssec.lithio.fr. CNz7ipxye839NwTm2C3xXpCisJaSWBpfgCe1ZMCakmZc0NZ+rODXPWi/ Z1E25CkuKEa86Rg/NGl3tcU56K2o0A==

On peut utiliser des outils comme dnsviz ou drill pour vérifier que tout marche bien.

Monitoring

Il convient bien sûr de surveiller nos signatures DNSSEC afin de voir si un souci arrive, pour cela on peut consulter la section 3.5 du document de l'AFNIC.

Stéphane Bortzmeyer a également fait un article sur le sujet avec Icinga.

Il existe d'autres solutions mais ce n'est pas l'objet de cet article.

Conclusion

Maintenant que notre zone DNS est signée, on peut avoir une confiance raisonnable dans les informations qui s'y trouvent (si on utilise un résolveur validant bien sûr), ce qui n'était pas forcement le cas avant.

Les KSK rollover et changements d'algorithmes feront peut-être l'objet d'un futur article (oui c'est risqué de dire ça je sais).

Merci à Jacques Foucry, Imriel, Stéphane Bortzmeyer et Baptiste Dauphin pour leur relecture et avis.

Installer son propre DNS avec Unbound

Un DNS (Domain Name Server) faisant authorité est comme son nom l'indique un serveur de noms de domaine : sur internet chaque machine est identifiée par son adresse IP, or il est difficile pour un être humain de retenir des adresses comme 88.191.250.176 et ceci pour chaque site web (à moins que vous ne soyez une base de données ambulante).

Les DNS font donc entre autres correspondre les noms de domaines aux adresses IP correspondantes.

Par exemple : linuxfr.org => 88.191.250.176

La plupart des gens utilisent les résolveurs DNS de leur fournisseur d'accès internet, cependant ces DNS sont souvent dit « menteurs », c'est à dire qu'ils ne renvoient pas la vrai adresse de certains sites (pour des raisons de censure dans le pays, …). Il est donc important d'avoir un DNS non-menteur afin de pouvoir naviguer librement, de plus les résolveurs de certains FAI peuvent souvent êtes plus lent que d'autres.

Quelles solutions à cela ?

1- Utiliser des DNS publiques comme ceux de OpenDNS ou Google

2- Installer son propre résolveur DNS

Mais comme Google connaît déjà assez de choses sur nous et que l'on aime la bidouille on va installer notre propre serveur. On se connecte à notre serveur, Raspberry, ordinateur personnelle ou autre machine Linux… et en root pour l'aventure !

Installer Unbound :

# apt-get install unbound

Récupérer la configuration des DNS racine :

# wget https://ftp.internic.net/domain/named.cache -O /var/lib/unbound/root.hints

Fichier de configuration de Unbound : /etc/unbound/unbound.conf

# Unbound configuration file for Debian.

server:

 

# Configuration de unbound pour DNSSEC

# en utilisant la clé des serveurs root

auto-trust-anchor-file: "/var/lib/unbound/root.key"

 

# Activer les logs

verbosity: 1

 

#Répondre aux requêtes DNS sur toutes les interfaces réseau.

interface: <votre-ipv4-ici>

interface: <votre-ipv6-ici>

 

#Port requêtes DNS

port: 53

 

#Activation de l'IPv4

do-ip4: yes

#Activation de l'IPv6

do-ip6: yes

 

# Activation udp

do-udp: yes

#Activation tcp

do-tcp: yes

 

#plages adresse ip autorisée à utiliser le DNS (mettez votre réseau)

access-control: 192.168.1.0/24 allow

 

#chemin du fichier root.hints avec les infos sur les DNS racine

root-hints: "/var/lib/unbound/root.hints"

 

#Cacher les infos sur le serveur DNS

hide-identity: yes

hide-version: yes

 

#paramètre limitant l'usurpation de DNS

harden-glue: yes

 

#Requérir les infos DNSSEC pour les zones de confiance

harden-dnssec-stripped: yes

 

#Options permettant de ne pas prendre la casse en compte lors des requêtes d'url.

use-caps-for-id: yes

 

#valeur mini de la TTL en secondes. Ne pas dépasser 1h

cache-min-ttl: 3600

#valeur max de la TTL en secondes.

cache-max-ttl: 86400

 

#activation du prefetch. Si un requête est faite lorsque la tll expire dans moins de 10% du temps qu'il lui est imparti

#le cache se mettra à jour aussitôt après avoir répondu à la requête.

prefetch: yes

 

#nombre de threads du DNS

num-threads: 1

 

# Tweaks et optimisations du cache

 

#Nombre de slabs à utiliser . Doit être une puissance de 2 du num-threads.

msg-cache-slabs: 8

rrset-cache-slabs: 8

infra-cache-slabs: 8

key-cache-slabs: 8

 

#Taille du cache en Mo:

rrset-cache-size: 51m

msg-cache-size: 25m

 

#Taille du buffer pour le port UPD en entrée. Evite la perte de message lors des requêtes

so-rcvbuf: 1m

 

#Renforcer la vie privée des adresses du LAN. Ne mettre que des adresses locales

private-address: 192.168.1.0/24

private-address: <votre-subnet-ipv6-ici>

 

#Si non nulles, les réponses indésirables ne sont pas seulement signalés dans les statistiques,

#mais aussi ajoutées à un total cumulé maintenu par thread.

#Si elle atteint le seuil, un avertissement est affiché et une action défensive est prise, le cache est vidé pour éviter l'empoissonnement DNS.

#Une valeur de 10000 est suggérée, la valeur par défaut est de 0 (service désactivé).

unwanted-reply-threshold: 10000

 

#Autorisé à répondre aux requêtes de localhost

do-not-query-localhost: no

 

# Est-ce que cette section supplémentaire doit être conservée intacte pour les données non-sécurisées

# Utile pour protéger les utilisateurs d'une validation de données potentiellement boguées

# Toutes les données non signés dans la section supplémentaire seront retirés des messages sécurisés

val-clean-additional: yes

On redémarre notre DNS :

# service unbound restart

Et vous voilà avec votre petit DNS fonctionnel, vous pourrez ainsi sûrement diminuer votre temps de réponse lors des requêtes DNS et ne pas subir les aléas politiques.